﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedGenomics.Workbench.Core;
using SharedGenomics.Workbench.Tests.TestObjects;

namespace SharedGenomics.Workbench.Tests.Core
{
    [TestClass]
    public class InitialisationActionPresenterInitialisationStageTests
    {
        private InitialiseActionPresenterInitialisationStage stage;
        private PresenterInitialisationContext context;
        private Rhino.Mocks.MockRepository mocks;

        [TestInitialize]
        public void Setup()
        {
            this.mocks = new Rhino.Mocks.MockRepository();
            this.stage = new InitialiseActionPresenterInitialisationStage();
            this.context = new PresenterInitialisationContext();
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void InitialiseShouldThrowIfArgumentNull()
        {
            this.stage.Initialise(null);
        }

        [TestMethod]
        public void ShouldCallInitAction()
        {
            bool actCalled = false;
            Action<IPresenter> initAction = p => { actCalled = true; };
            IPresenter presenter = this.mocks.Stub<IPresenter>();

            this.context.InitialisationAction = initAction;
            this.context.Current = presenter;

            this.stage.Initialise(context);
            Assert.IsTrue(actCalled);
        }

        [TestMethod]
        public void ShouldNotCallActionIfNull()
        {
            this.context.Current = this.mocks.Stub<IPresenter>();
            this.stage.Initialise(context);

            //test passes if no exceptions are thrown
        }

        [TestMethod]
        public void ShouldNotCallActionIfPresenterNull()
        {
            bool actCalled = false;
            Action<IPresenter> initAction = p => { actCalled = true; };
            IPresenter presenter = this.mocks.Stub<IPresenter>();

            this.context.InitialisationAction = initAction;
            this.stage.Initialise(context);

            Assert.IsFalse(actCalled);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void ShouldThrowIfActionHasWrongNumberOfParameters()
        {
            Action<IPresenter, string> initAction = (p, s) => { };

            this.context.InitialisationAction = initAction;
            this.context.Current = this.mocks.Stub<IPresenter>();

            this.stage.Initialise(context);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void ShouldThrowIfActionParameterIsWrongType()
        {
            Action<StubPresenter> initAction = p => { };

            this.context.InitialisationAction = initAction;
            this.context.Current = this.mocks.Stub<IPresenter>();

            this.stage.Initialise(context);
        }
    }
}
